﻿namespace EasyToolkit.Excel.Application
{
    using System;
    using Microsoft.Office.Interop.Excel;
    using EasyToolkit.Excel.BindingTemplates;

    /// <summary>
    /// Use to freeze the Excel execution the time to execute operations.
    /// Reduce the flickering during multiple updates on cells in the current Excel application.
    /// </summary>
    public class FreezeExcel : IDisposable
    {
        private static int requestsCpt = 0;
        private static object objSync = new object();

        private bool disposed;
        private Application application;
        private bool screenUpdating;
        private bool enableEvents;
        private bool displayStatusBar;
        private XlCalculation calculationMode;

        public FreezeExcel(Application application)
        {
            this.application = application;
            lock (objSync)
            {
                requestsCpt++;
                if (! ((ExcelBindingTemplateManager) ExcelBindingTemplateManager.Instance).ExcelApplication.IsInEditMode())
                {
                    if (requestsCpt == 1)
                    {
                        screenUpdating = this.application.ScreenUpdating;
                        enableEvents = this.application.EnableEvents;
                        displayStatusBar = this.application.DisplayStatusBar;
                        calculationMode = this.application.Calculation;

                        this.application.ScreenUpdating = false;
                        this.application.EnableEvents = false;
                        this.application.DisplayStatusBar = false;
                        this.application.Calculation = XlCalculation.xlCalculationManual;
                    }
                }
            }
        }

        ~FreezeExcel()
        {
            Dispose();
        }

        public void Dispose()
        {
            if (!disposed)
            {
                disposed = true;
                lock (objSync)
                {
                    requestsCpt--;
                    if (! ((ExcelBindingTemplateManager) ExcelBindingTemplateManager.Instance).ExcelApplication.IsInEditMode())
                    {
                        if (requestsCpt == 0)
                        {
                            this.application.ScreenUpdating = screenUpdating;
                            this.application.EnableEvents = enableEvents;
                            this.application.DisplayStatusBar = displayStatusBar;
                            this.application.Calculation = calculationMode;

                            this.application = null;
                        }
                    }
                }
            }
        }
    }
}
